/*************************************************************************
 * This file is part of HeroesForge.
 *
 * HeroesForge is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * HeroesForge is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with HeroesForge.  If not, see <http://www.gnu.org/licenses/>.
 *************************************************************************/
package org.diskordia.heroesforge.console;

import org.diskordia.heroesforge.client.IClientContext;
import org.diskordia.heroesforge.client.preferences.IConnectionInfo;
import org.diskordia.heroesforge.console.commands.CancelCommand;
import org.diskordia.heroesforge.console.commands.ConnectCommand;
import org.diskordia.heroesforge.console.threading.AuthenticateTask;
import org.diskordia.heroesforge.core.security.SaltedHash;

import com.google.inject.Inject;
import com.google.inject.Provider;

/**
 * Presenter which controls the connection dialogue GUI.
 * 
 * @author lehmamic
 */
public class ConnectionDialogPresenter {
	private final static String PLACEHOLDER = "X3ht41984meEts23";
	
	private IConnectionDialogView connectionDialog;
	private IClientContext clientContext;
	
	private Provider<AuthenticateTask> authenticationTaskProvider;
	
	/**
	 * Initializes an instance of the @see ConnectionDialogPresenter class.
	 *
	 * @param view
	 */
	@Inject
	public ConnectionDialogPresenter(IConnectionDialogView view, IClientContext context, Provider<AuthenticateTask> authenticationTaskInjectionProvider)
	{
		if(view == null){
			throw new IllegalArgumentException("The view instance is a null reference.");
		}
		
		if(context == null){
			throw new IllegalArgumentException("The context instance is a null reference.");
		}
		
		if(authenticationTaskInjectionProvider == null)
		{
			throw new IllegalArgumentException("The authenticationTaskInjectionProvider instance is a null reference.");
		}
		
		this.setConnectionDialog(view);
		this.setClientContext(context);
		this.authenticationTaskProvider = authenticationTaskInjectionProvider;
		
		this.ShowStoredValues();
		this.InjectCommands();
	}
	
	private void ShowStoredValues()
	{
		IConnectionInfo connectionInfo = this.getClientContext().getPreferences().getServerConnection();
		IConnectionDialogView view = this.getConnectionDialog();
		view.setServerUrl(connectionInfo.getServerUrl());
		view.setUserName(connectionInfo.getUserName());
		view.setAutoConnect(connectionInfo.isAutoConnect());
		
		String password = connectionInfo.getPassword();
		if(password.equals(""))
		{
			view.setPassword(connectionInfo.getPassword());
		}
		else
		{
			view.setPassword(PLACEHOLDER);
		}
	}
	
	private void InjectCommands()
	{
		this.getConnectionDialog().setCommandConnect(new ConnectCommand(this));
		this.getConnectionDialog().setCommandCancel(new CancelCommand(this));
	}
	
	/**
	 * Collects and validates the entered connection information.
	 */
	public void CollectConnectionInformation(){
		IConnectionInfo connectionInfo = this.getClientContext().getPreferences().getServerConnection();
		IConnectionDialogView view = this.getConnectionDialog();
		
		connectionInfo.setServerUrl(view.getServerUrl());
		connectionInfo.setAutoConnect(view.isAutoConnect());
		
		connectionInfo.setUserName(view.getUserName());
		
		String password = view.getPassword();
		if(!password.equals(PLACEHOLDER)){
			SaltedHash digest = new SaltedHash(connectionInfo.getUserName().trim());
			String saltedHash = digest.GenerateHash(password.trim());
			
			connectionInfo.setPassword(saltedHash);
		}
	}
	
	/**
	 * Authenticates the client on the configured server.
	 */
	public void AuthenticateOnServer()
	{
		AuthenticateTask task = this.authenticationTaskProvider.get();
		task.execute();
	}
	
	/**
	 * Close the connection dialog.
	 */
	public void CloseDialog(){
		this.getConnectionDialog().CloseView();
	}

	/**
	 * @param connectionDialog the connectionDialog to set
	 */
	private void setConnectionDialog(IConnectionDialogView connectionDialog) {
		this.connectionDialog = connectionDialog;
	}

	/**
	 * @return the connectionDialog
	 */
	public IConnectionDialogView getConnectionDialog() {
		return connectionDialog;
	}

	/**
	 * @param clientContext the clientContext to set
	 */
	private void setClientContext(IClientContext context) {
		this.clientContext = context;
	}

	/**
	 * @return the clientContext
	 */
	public IClientContext getClientContext() {
		return this.clientContext;
	}
}
